home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 033a / obul_003.zip / OBUL.C < prev    next >
C/C++ Source or Header  |  1991-04-18  |  35KB  |  1,135 lines

  1. /*--------------------------------------------------------------*/
  2. /*  Copyright 1991                          */
  3. /*  Keith Ford; All Rights Reserved                */
  4. /*--------------------------------------------------------------*/
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <time.h>
  9. #include <math.h>
  10. #include <malloc.h>
  11. #include <conio.h>                           /* Std console I/O def's   */
  12. #include <string.h>                          /* Std string func defs    */
  13. #include <stdlib.h>                          /* Miscellaneous def's     */
  14. #include "otoolkit.h"                        /* ToolKit General Headers */
  15. #include "otoollib.h"                        /* ToolKit Func Prototypes */
  16.  
  17.  
  18. #define VERSION 003
  19.  
  20. #define MAX_NUM_BULLETS 20
  21. #define KEY_SIZE 32
  22. #define DATUM_SIZE 80
  23. #define LINE_SIZE 80
  24. #define COLOR_SIZE 13
  25. #define MAX(a,b) ((a)>(b)?(a):(b))
  26. #define UP(s_) {int i;for(i=0;*(s_+i);i++)*(s_+i)=(char)toupper(*(s_+i));}
  27.  
  28. #define MAX_LABELS 4
  29. enum address_type {loop_address, privileged_address, help_address, credit_address};
  30. long label_address[MAX_LABELS]={loop_address, privileged_address, help_address, credit_address};
  31.  
  32. /* UGH! - Globals */
  33. struct _lu_file lu;
  34. struct _usr u;
  35. FILE *lu_file, *log_file;
  36. struct tm *td;
  37. short num_bulletins_available;
  38. char ba[MAX_NUM_BULLETS];
  39.  
  40. char temp_datum_[DATUM_SIZE];
  41. char string_[DATUM_SIZE];
  42. char string2_[DATUM_SIZE];
  43. char *opt_ptr_;
  44. char *path_ptr_;
  45. char ctl_file_[DATUM_SIZE];
  46. char prm_file_[DATUM_SIZE];
  47. char prm_bkup_[DATUM_SIZE];
  48. char n_help_text;
  49. char any_new=0;
  50. char help_text_[20][80];
  51. short num_columns;
  52. long foffset2;
  53. long _now;
  54. #define n_credit_text 20
  55. static char *credit_text_[n_credit_text]={
  56.   "OBUL created by Keith Ford, sysop of Micro Magic 1:373/12",
  57.   "with special thanks going to the following.",
  58.   "",
  59.   "Opus Computer Based Information System",
  60.   "Originally conceived, produced, and copyrighted (c) 1986-1990",
  61.   "by Wynn Wagner III, further developed and copyrighted (c) 1986-1990",
  62.   "by Wynn Wagner III, Doug Boone, George Stanislav,",
  63.   "Vince Perriello, Rick Huebner, and Tom Kashuba.",
  64.   "",
  65.   "Utility Programmer's Tool Kit",
  66.   "Version 1.10 - Mar 11, 1990",
  67.   "Prepared by: Tom Kashuba",
  68.   "",
  69.   "OECC - The High Touch Language Compiler",
  70.   "Version 1.00, by George A. Stanislav",
  71.   "",
  72.   "John Emmert of GATEWAY for helping me with Opus.",
  73.   "Scott Williams, for helping with the name: OBUL.",
  74.   "Rush & Tesla, for providing the development music.",
  75.   "Carol & Emily, love you both!"};
  76.  
  77.  
  78.  
  79. struct obul_002_header
  80. {
  81.   short version;
  82.   char lastpath_[DATUM_SIZE];
  83.   char bbs, oec;
  84.   char path_[DATUM_SIZE];
  85.   char columns;
  86.   char order;
  87.   char title_text_[DATUM_SIZE];
  88.   char title_color_[COLOR_SIZE];
  89.   char prompt_color_[COLOR_SIZE];
  90.   char number_of_bulletins;
  91.   char display_privileged;
  92.   char format_[10];
  93.   char lead_character;
  94.   char lead_color_[COLOR_SIZE];
  95.   char choice_color_[COLOR_SIZE];
  96.   char tail_character;
  97.   char tail_color_[COLOR_SIZE];
  98.   char entry_color_[COLOR_SIZE];
  99.   char highlight_character;
  100.   char highlight_color_[COLOR_SIZE];
  101.   char highlight_blink;
  102. } header;
  103.  
  104. struct obul_002_bullet
  105. {
  106.   char choice_character;
  107.   char entry_text_[DATUM_SIZE];
  108.   char access;            /* Read_Obul_Prm will change to 1 or 0 */
  109.   char file_[DATUM_SIZE];
  110.   char highlight_mode;
  111. } *bullet;
  112.  
  113. #define BULLET_STRUCT (struct obul_002_bullet *)
  114. #define BULLET_SIZE   (sizeof(struct obul_002_bullet))
  115. #define NEW_BULLET    (BULLET_STRUCT calloc( 1,BULLET_SIZE))
  116.  
  117. char Translate_Color();
  118.  
  119.  
  120.  
  121. main( argc, argv)
  122. int argc;
  123. char *argv[];
  124.  
  125. {
  126.   FILE *f;
  127.   short status,i,len;
  128.  
  129.   log_file=fopen("obul.log","w");
  130.   tzset();
  131.   time(&_now);
  132.   fprintf(log_file,"time = %ld = %s",_now,ctime(&_now));
  133.   fprintf(log_file,"argc=%d\n",argc);
  134.   for(i=0;i<argc;i++)fprintf(log_file,"arg%02d=%s\n",argv[i]);
  135.   opt_ptr_ = argv[1];
  136.   path_ptr_ = argv[2];
  137.   if( argc == 3)
  138.   {
  139.     len = strlen( path_ptr_);
  140.     if( path_ptr_[len-1] != '\\') strcat( path_ptr_,"\\");
  141.     strcpy( ctl_file_, path_ptr_);
  142.     strcpy( prm_file_, path_ptr_);
  143.     strcpy( prm_bkup_, path_ptr_);
  144.   }
  145.   strcat( ctl_file_,"obul.ctl");
  146.   strcat( prm_file_,"obul.prm");
  147.   strcat( prm_bkup_,"obul_prm.bak");
  148.     
  149.   if( (argc >= 2) &&( (opt_ptr_[0]=='-')||(opt_ptr_[0]=='/')) && ((opt_ptr_[1]=='c')||(opt_ptr_[1]=='C')))
  150.   {
  151.     /* compile control file to parameter file */
  152.     status = Read_Obul_Ctl();
  153.     if( status)
  154.     {
  155.       printf("status: %03d in Read_Obul_Ctl()",status);
  156.       switch( status)
  157.       {
  158.         case 1: puts("unable to open obul.ctl"); break;
  159.         case 2: puts("parameter ERROR"); break;
  160.       }
  161.     }
  162.     else
  163.     {
  164.       f = fopen( prm_file_, "rb" );
  165.       if( f )
  166.       {
  167.         fclose( f );
  168.         strcpy( string_, "copy ");
  169.         strcat( string_, prm_file_);
  170.         strcat( string_, " ");
  171.         strcat( string_, prm_bkup_);
  172.         system( string_);
  173.       }
  174.       status = Write_Obul_Prm();
  175.       if( status)
  176.       {
  177.         printf("status: %03d in Write_Obul_Prm()",status);
  178.         puts("unable to open obul.ctl");
  179.       }
  180.     }
  181.   }
  182.   else if( (argc >= 2) && ((opt_ptr_[0]=='-')||(opt_ptr_[0]=='/')) && ((opt_ptr_[1]=='d')||(opt_ptr_[1]=='D')))
  183.   {
  184.     /* decompile parameter file into control file */
  185.     status = Read_Obul_Prm();
  186.     if( status)
  187.     {
  188.       printf("status: %03d in Read_Obul_Prm()",status);
  189.       fclose(log_file);
  190.       exit( 1);
  191.     }
  192.     status = Write_Obul_Ctl();
  193.     if( status)
  194.     {
  195.       printf("status: %03d in Write_Obul_Ctl()",status);
  196.       fclose(log_file);
  197.       exit( 1);
  198.     }
  199.   }
  200.   else if ((argc >= 2) && ((opt_ptr_[0]=='-')||(opt_ptr_[0]=='/')) && ((opt_ptr_[1]=='m')||(opt_ptr_[1]=='M')))
  201.   {
  202.     /* display interface menu */
  203.     printf("\n\nThe menu option has yet to be implemented.\n\n");
  204.   }
  205.   else if ((argc >= 2) && ((opt_ptr_[0]=='-')||(opt_ptr_[0]=='/')) && ((opt_ptr_[1]=='g')||(opt_ptr_[1]=='G')))
  206.   {
  207.     /*generate bulletin file */
  208.  
  209.     /* user information */
  210.     num_columns = 79;
  211.  
  212.     /* read compiled paramters */
  213.     status = Read_Obul_Prm();
  214.     if (status)
  215.     {
  216.       printf("status: %03d in Read_Obul_Prm()",status);
  217.       fclose(log_file);
  218.       exit (1);
  219.     }
  220.  
  221.     /* read LASTUS## file to get time of last login and other info */
  222.     if(( lu_file = fopen( header.lastpath_, "rb" )) == NULL )
  223.     {
  224.       fprintf( stderr, "Can't open [%s]\n", header.lastpath_ );
  225.       fclose(log_file);
  226.       exit( 99 );
  227.     }
  228.     fread( (char*)&lu, sizeof(lu), 1, lu_file );
  229.     u = lu.user;
  230.     fclose (lu_file);
  231.  
  232.     /* log user info */
  233.     fprintf(log_file, "User: %s", lu.user.name );
  234.     if ( *lu.user.alias ) fprintf(log_file, " [%-.36s]", lu.user.alias );
  235.     fprintf(log_file,"\n");
  236.     fprintf(log_file, "City.....: %-.36s\n", *lu.user.city ? lu.user.city : "(none)" );
  237.     fprintf(log_file, "Privilege: %-6.6s  Keys: %-32.32s\n",
  238.             pv2pn(lu.user.ClassPriv), ky2st(0,lu.user.ClassLock) );
  239.     fprintf(log_file, "Laston in LASTUS00.DAT says: %s\n",lu.laston);
  240.     fprintf(log_file, "Calls...#: %-6d  ", lu.user.times );
  241.     if ( lu.user.ludate > 0L )
  242.     {
  243.        td = localtime( &lu.user.ludate );
  244.        fprintf(log_file, "Last: %02d-%02d-%02d %02d:%02d  ",
  245.                td->tm_year, td->tm_mon+1, td->tm_mday,
  246.                td->tm_hour, td->tm_min                  );
  247.     }
  248.     else
  249.        fprintf(log_file, "Last: .. .. .. .. ..  " );
  250.  
  251.     if ( lu.user.fudate > 0L )
  252.     {
  253.        td = localtime( &lu.user.fudate );
  254.        fprintf(log_file, "1st: %02d-%02d-%02d %02d:%02d\n",
  255.                td->tm_year, td->tm_mon+1, td->tm_mday,
  256.                td->tm_hour, td->tm_min                  );
  257.     }
  258.     else
  259.        fprintf(log_file, "1st: .. .. .. .. ..\n" );
  260.     fprintf(log_file, "Password.: %-.16s\n", *lu.user.pwd ? lu.user.pwd : "(none)" );
  261.     fprintf(log_file, "MenuLevel: %s\n", mv2mn(lu.user.help) );
  262.     fprintf(log_file, "DsplayRxC: %d x %d\n\n", lu.user.len+2, lu.user.width+2 );
  263.  
  264.             fprintf(log_file,"\n");
  265.             for (i=0; i < 60; i++)
  266.                fprintf(log_file, "-" );
  267.             fprintf(log_file,"\n");
  268.  
  269.             fprintf(log_file, "User: %s", u.name );
  270.             if ( *u.alias )
  271.                fprintf(log_file, " [%-.36s]", u.alias );
  272.             fprintf(log_file,"\n");
  273.  
  274.             fprintf(log_file, "City.....: %-.36s\n", *u.city ? u.city : "(none)" );
  275.  
  276.             fprintf(log_file, "Privilege: %-6.6s  Keys: %-32.32s\n",
  277.                     pv2pn(u.ClassPriv), ky2st(0,u.ClassLock) );
  278.  
  279.             fprintf(log_file, "Calls...#: %-6d  ", u.times );
  280.  
  281.  
  282.             if ( u.ludate > 0L )
  283.             {
  284.                td = localtime( &u.ludate );
  285.                fprintf(log_file, "Last: %02d-%02d-%02d %02d:%02d  ",
  286.                        td->tm_year, td->tm_mon+1, td->tm_mday,
  287.                        td->tm_hour, td->tm_min                  );
  288.             }
  289.             else
  290.                fprintf(log_file, "Last: .. .. .. .. ..  " );
  291.  
  292.             if ( u.fudate > 0L )
  293.             {
  294.                td = localtime( &u.fudate );
  295.                fprintf(log_file, "1st: %02d-%02d-%02d %02d:%02d\n",
  296.                        td->tm_year, td->tm_mon+1, td->tm_mday,
  297.                        td->tm_hour, td->tm_min                  );
  298.             }
  299.             else
  300.                fprintf(log_file, "1st: .. .. .. .. ..\n" );
  301.  
  302.             if ( u.exflag & EXPBYDATE )
  303.             {
  304.                if ( u.xdate != 0L )
  305.                {
  306.                   td = gmtime( &u.xdate );
  307.                   fprintf(log_file, "ExpryDate: %02d-%02d-%02d %02d:%02d:%02d\n",
  308.                           td->tm_year, td->tm_mon+1, td->tm_mday,
  309.                           td->tm_hour, td->tm_min,   td->tm_sec   );
  310.                }
  311.                else
  312.                   fprintf(log_file, "ExpryDate: (none)\n" );
  313.             }
  314.  
  315.             if ( u.exflag & EXPBYMINS )
  316.             {
  317.                if ( u.dbmin )
  318.                {
  319.                   fprintf(log_file, "Expcrmin: %-5ld  dbmin: %-5ld  Bal: %-5ld\n",
  320.                            u.crmin, u.dbmin, u.crmin-u.dbmin );
  321.                }
  322.                else
  323.                   fprintf(log_file, "ExpryMins: (none)\n" );
  324.             }
  325.  
  326.             if ( u.exflag & (EXPBYDATE|EXPBYMINS) )
  327.             {
  328.                if ( !(u.exflag & (EXPAXE|EXPDEMOTE)) )
  329.                   fprintf(log_file, "ExpMethod: (none)\n" );
  330.                else
  331.                   fprintf(log_file, "ExpMethod: %s%s\n",
  332.                            (u.exflag & EXPDEMOTE) ? "DEMOTE " : "",
  333.                            (u.exflag & EXPAXE   ) ? "AXE"     : ""  );
  334.             }
  335.  
  336.             fprintf(log_file, "Password.: %-.16s\n", *u.pwd ? u.pwd : "(none)" );
  337.             fprintf(log_file, "LangSetNo: %d\n", u.language );
  338.  
  339.             fprintf(log_file, "MdmTel...: %-.16s\n",
  340.                      *u.usrtel ? u.usrtel : "(none)" );
  341.  
  342.             fprintf(log_file, "MenuLevel: %s\n", mv2mn(u.help) );
  343.  
  344.             fprintf(log_file, "UpLds....: %ldk  DnLds: %ldk  Up/DnLd%%: %ld\n",
  345.                                 u.upld, u.dnld,
  346.                                 (u.dnld > 0L) ?
  347.                                 (100L * u.upld)/u.dnld : 0L );
  348.  
  349.             fprintf(log_file, "DsplayRxC: %d x %d\n", u.len+2, u.width+2 );
  350.  
  351.             fprintf(log_file, "FidoNet-$: $%d.%02dC - $%d.%02dD = $%d.%02d\n",
  352.                                 u.credit / 100, u.credit % 100,
  353.                                 u.debit  / 100, u.debit  % 100,
  354.                                 (u.credit-u.debit) / 100,
  355.                                 (u.credit-u.debit) % 100  );
  356.  
  357.             fprintf(log_file, "SpcAnn#'s:" );
  358.             for (i=0; i < 5; i++)
  359.                fprintf(log_file, " %03d", u.saccnt[i] );
  360.             fprintf(log_file, "   SpclWelc: %-.8s\n",
  361.                     *u.spcoec ? u.spcoec : "(none)" );
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.     /* determine file accesses */
  369.     fprintf(log_file,"user priv = %d\n", lu.user.ClassPriv);
  370.     num_bulletins_available = 0;
  371.     for (i=0; i<header.number_of_bulletins; i++)
  372.     {
  373.       fprintf(log_file,"bullet[%d] priv = %d\n", i, pl2pv((char)toupper(bullet[i].access)));
  374.       if ((lu.user.ClassPriv >= pl2pv((char)toupper(bullet[i].access))) ||
  375.           (bullet[i].file_[0]=='*'))
  376.       {
  377.         bullet[i].access = 1;
  378.         ba[num_bulletins_available++]=i;
  379.       }
  380.       else
  381.       {
  382.         bullet[i].access = 0;
  383.         if (header.display_privileged) ba[num_bulletins_available++]=i;
  384.       }
  385.     }
  386.  
  387.     /* generate the bulletin menu files */
  388.     status = Write_Obul_Menu();
  389.     if (status)
  390.     {
  391.       printf("status: %03d in Write_Obul_Menu",status);
  392.       fclose(log_file);
  393.       exit (1);
  394.     }
  395.   }
  396.   else if ((argc >= 2) && ((opt_ptr_[0]=='-')||(opt_ptr_[0]=='/')) && ((opt_ptr_[1]=='?')||(opt_ptr_[1]=='h')||(opt_ptr_[1]=='H')))
  397.   {
  398.     for( i=0; i<n_credit_text; i++ )
  399.     {
  400.       printf("%s\n",credit_text_[i]);
  401.     }
  402.   }
  403.   else 
  404.   {
  405.     /* display usage information */
  406.     printf (" ");  /*control-L*/
  407.     puts (" ");
  408.     puts ("OBUL - Opus Bulletin Utilization Language");
  409.     printf("       Version %03d released 20-APR-91\n", VERSION);
  410.     puts ("       Copyright 1991 Keith Ford.  All Rights Reserved.");
  411.     puts (" ");
  412.     puts ("Usage: OBUL [option] [drive:\\path\\]");
  413.     puts ("Options are:");
  414.     puts ("  -?,-h = display more information");
  415.     puts ("  -c = compile OBUL.CTL into OBUL.PRM");
  416.     puts ("  -g = generate .BBS/.OEC from OBUL.PRM and LASTUS##.DAT");
  417.     puts ("  -d = decompile OBUL.PRM to screen (stdout)");
  418.     puts ("  -m = display OBUL menu interface");
  419.     puts ("drive:\\path\\ = drive and path where files are located.");
  420.     puts ("               Default is current directory.  See manual.");
  421.     puts (" ");
  422.   }
  423.   fclose(log_file);
  424. }
  425.  
  426.  
  427.  
  428.  
  429.  
  430. /********************************************************************/
  431. int Get_Next_Line (_fp, key_to_match, key_word, datum_string_)
  432. FILE *_fp;
  433. char *key_word, *datum_string_, *key_to_match;
  434. {
  435.   char line[LINE_SIZE];
  436.   short i,j;
  437.   while (!feof(_fp))
  438.   {
  439.     fgets (line, LINE_SIZE, _fp);
  440.     if (isalpha (line[0]))
  441.     {
  442.       /* null out the strings */
  443.       for (i=0; i<KEY_SIZE; i++) key_word[i]=0;
  444.       for (i=0; i<DATUM_SIZE; i++) datum_string_[i]=0;
  445.       for (i=0; i<DATUM_SIZE; i++) temp_datum_[i]=0;
  446.  
  447.       /* parse input line for key word and datum string */
  448.       for (i=0; isgraph(line[i]); i++) key_word[i]=tolower(line[i]);
  449.       if (strcmp (key_to_match, key_word)) return (4);
  450.       for (; isspace(line[i]); i++);
  451.       for (j=0; isprint(line[i]); j++,i++)
  452.       {
  453.         datum_string_[j] = tolower(line[i]);
  454.         temp_datum_[j] = line[i];
  455.       }
  456.  
  457.       /* error of 1 if no key word */
  458.       if (!strlen(key_word)) return (1);
  459.       /* error of 2 if no datum string */
  460.       if (!strlen(datum_string_)) return (2);
  461.       /* return successfully */
  462.       return (0);
  463.  
  464.     } /* if isalpha */
  465.   } /* while !feof */
  466.  
  467.   /* error of 3 if EOF reached */
  468.   return (3);
  469. } /* Get_Next_Line() */
  470.  
  471.  
  472.  
  473.  
  474. /********************************************************************/
  475. int Read_Obul_Ctl ()
  476. {
  477.   short status;
  478.   char key[ KEY_SIZE ], datum_[ DATUM_SIZE ];
  479.   char *ptr2char;
  480.   char line[LINE_SIZE];
  481.   short i,j,bullet_num;
  482.   int len;
  483.   long foffset;
  484.   FILE *_f,*_tf;
  485.  
  486. # define ROC_IO(K) \
  487.   status=Get_Next_Line(_f,K,key,datum_);if(status){printf("ERR%03d: ",status);\
  488.   switch(status){case 1:puts("no key word found");break;\
  489.   case 2:puts("no datum found");break;case 3:puts("EOF reached");break;\
  490.   case 4:printf("key mismatch: |%s|%s|\n",K,key);break;}return(2);}else
  491.  
  492.  
  493.   if ((_f = fopen( ctl_file_, "r" ) ) == 0)
  494.   {
  495.     printf( "ERROR opening %s\n", ctl_file_ );
  496.     return( 1 );
  497.   }
  498.  
  499.   ROC_IO("version")
  500.   {
  501.     header.version = (short) atoi( datum_ );
  502.     if ((header.version != 1) && (header.version != 2))
  503.       printf( "warning:  bad version number\n");
  504.   }
  505.  
  506.   ROC_IO("lastpath")
  507.   {
  508.     strcpy (header.lastpath_, datum_);
  509.     len = strlen (header.lastpath_);
  510.   }
  511.  
  512.   ROC_IO("path")
  513.   {
  514.     strcpy (header.path_, datum_);
  515.     len = strlen (header.path_);
  516.     if (header.path_[len-4] == '.') header.path_[len-4] = 0;
  517.   }
  518.  
  519.   ROC_IO("bbs")
  520.   {
  521.     header.bbs = (char) (datum_[0]=='y');
  522.   }
  523.   ROC_IO("oec")
  524.   {
  525.     header.oec = (char) (datum_[0]=='y');
  526.   }
  527.   if (!header.bbs && !header.oec)
  528.   {
  529.     status=2;
  530.     printf ("ERROR:  no bbs or oec specified\n");
  531.   }
  532.  
  533.   ROC_IO("columns")
  534.   {
  535.     if (datum_[0]=='a')
  536.       header.columns = 0;
  537.     else
  538.       header.columns = (char) atoi( datum_ );
  539.     if ((header.columns<0) || (header.columns>4))
  540.     {
  541.       status=2;
  542.       printf ("ERROR:  invalid number of columns:  %s\n", datum_);
  543.     }
  544.   }
  545.  
  546.   ROC_IO("order")
  547.   {
  548.     header.order = (char) (datum_[0]=='a');
  549.   }
  550.  
  551.   ROC_IO("title_text")
  552.   {
  553.     strcpy (header.title_text_, temp_datum_);
  554.   }
  555.  
  556.   ROC_IO("title_color")
  557.   {
  558.     strcpy( header.title_color_, datum_ );
  559.   }
  560.  
  561.   ROC_IO("prompt_color")
  562.   {
  563.     strcpy( header.prompt_color_, datum_ );
  564.   }
  565.  
  566.   ROC_IO("display_privileged")
  567.   {
  568.     header.display_privileged = (char) (datum_[0]=='y');
  569.   }
  570.  
  571.   ROC_IO("format")
  572.   {
  573.     strcpy( header.format_, datum_ );
  574.   }
  575.   
  576.   ROC_IO("lead_character")
  577.   {
  578.     if (datum_[1] == 'p') datum_[0]=' ';
  579.     else if (datum_[1] == 'u') datum_[0]=0;
  580.     header.lead_character = datum_[0];
  581.   }
  582.   
  583.   ROC_IO("lead_color")
  584.   {
  585.     strcpy( header.lead_color_, datum_ );
  586.   }
  587.   
  588.   ROC_IO("choice_color")
  589.   {
  590.     strcpy( header.choice_color_, datum_ );
  591.   }
  592.   
  593.   ROC_IO("tail_character")
  594.   {
  595.     if (datum_[1] == 'p') datum_[0]=' ';
  596.     else if (datum_[1] == 'u') datum_[0]=0;
  597.     header.tail_character = datum_[0];
  598.   }
  599.   
  600.   ROC_IO("tail_color")
  601.   {
  602.     strcpy( header.tail_color_, datum_ );
  603.   }
  604.   
  605.   ROC_IO("entry_color")
  606.   {
  607.     strcpy( header.entry_color_, datum_ );
  608.   }
  609.   
  610.   ROC_IO("highlight_character")
  611.   {
  612.     header.highlight_character = datum_[0];
  613.   }
  614.   
  615.   ROC_IO("highlight_color")
  616.   {
  617.     strcpy( header.highlight_color_, datum_ );
  618.   }
  619.   
  620.   ROC_IO("highlight_blink")
  621.   {
  622.     header.highlight_blink = (char) (datum_[0]=='y');
  623.   }
  624.  
  625.   /* mark where bullets start */
  626.   foffset = ftell( _f );
  627.  
  628.   /* allow 2 bullets for help and credits */
  629.   header.number_of_bulletins = 2;
  630.   while( !feof( _f ))
  631.   {
  632.     fgets (line, LINE_SIZE, _f);
  633.     UP(line);
  634.     if( !strncmp( line, "# HELP TEXT", 11 ))
  635.     {
  636.       /* mark where help starts */
  637.       foffset2 = ftell( _f );
  638.       break;
  639.     }
  640.     if (!strncmp(line,"CHOICE_C",8))
  641.       ++header.number_of_bulletins;
  642.   }
  643.  
  644.   if ((header.number_of_bulletins<0) ||
  645.       (header.number_of_bulletins>MAX_NUM_BULLETS))
  646.   {
  647.     status=2;
  648.     printf ("ERROR:  invalid number of bulletins:  %s\n", datum_);
  649.     return(status);
  650.   }
  651.   fseek( _f, foffset, 0 );
  652.   bullet = BULLET_STRUCT
  653.            calloc (1, header.number_of_bulletins*BULLET_SIZE);
  654.  
  655.   for (bullet_num=0; bullet_num<header.number_of_bulletins-2; bullet_num++)
  656.   {
  657.     printf("processing bullet #%d\n",bullet_num);
  658.  
  659.     ROC_IO("choice_character")
  660.     {
  661.       bullet[bullet_num].choice_character = temp_datum_[0];
  662.     }
  663.  
  664.     ROC_IO("entry_text")
  665.     {
  666.       strcpy( bullet[bullet_num].entry_text_, temp_datum_ );
  667.     }
  668.     
  669.     ROC_IO("access")
  670.     {
  671.       bullet[bullet_num].access = datum_[0];
  672.       /* Hidden Sysop Asstsysop Clerk Extra Favored
  673.        Privil Worthy Normal Limited Disgrace Twit*/
  674.     }
  675.     
  676.     ROC_IO("file")
  677.     {
  678.       strcpy( bullet[bullet_num].file_, temp_datum_ );
  679.       if (bullet[bullet_num].file_[0] == '*')
  680.       {
  681.         if (strcmp(bullet[bullet_num].file_,"*quit") &&
  682.             strcmp(bullet[bullet_num].file_,"*hangup"))
  683.           printf("  *** error:  unknown file \"%s\"\n",bullet[bullet_num].file_);
  684.       }
  685.       else
  686.       {
  687.         _tf = fopen(temp_datum_,"r");
  688.         if (!_tf) printf("  *** warning:  could not open %s\n",temp_datum_);
  689.         else fclose(_tf);
  690.       }
  691.     }
  692.     
  693.     ROC_IO("highlight_mode")
  694.     {
  695.       switch (datum_[1])
  696.       {
  697.         case 'e': bullet[bullet_num].highlight_mode = 0; break;
  698.         case 'l': bullet[bullet_num].highlight_mode = 1; break;
  699.         case 'u': bullet[bullet_num].highlight_mode = 2; break;
  700.         default:  printf("ERROR:  invalid highlight mode:  %s\n",temp_datum_); break;
  701.       }
  702.     }
  703.   }
  704.  
  705.   /* read in Help Text */
  706.   fseek( _f, foffset2, 0 );
  707.   for( i=0; (i<20)&&(!feof(_f)); i++ )
  708.     fgets( help_text_[i], 80, _f );
  709.   n_help_text = i;
  710.  
  711.   /* create bullet entries for Credits & Help */
  712.   bullet[bullet_num].choice_character = '=';
  713.   strcpy( bullet[bullet_num].entry_text_, "OBUL credits" );
  714.   bullet[bullet_num].access = 'T';
  715.   strcpy( bullet[bullet_num].file_, "*credits" );
  716.   bullet[bullet_num].highlight_mode = 0;
  717.   ++bullet_num;
  718.   bullet[bullet_num].choice_character = '?';
  719.   strcpy( bullet[bullet_num].entry_text_, "Help" );
  720.   bullet[bullet_num].access = 'T';
  721.   strcpy( bullet[bullet_num].file_, "*help" );
  722.   bullet[bullet_num].highlight_mode = 0;
  723.  
  724.   fclose (_f);
  725.   return (0);
  726.  
  727. } /* Read_Obul_Ctl() */
  728.  
  729.  
  730.  
  731.  
  732. /********************************************************************/
  733. char Translate_Color (color_name_)
  734. char *color_name_;
  735. {
  736.   char color_number,letter;
  737.   color_number = 30;
  738.   if ((color_name_[0] == 'b') && (color_name_[1] == 'r'))
  739.   {
  740.     color_number |= 0x80;
  741.     letter = 6;
  742.   }
  743.   else letter = 0;
  744.   switch (color_name_[letter])
  745.   {
  746.     case 'r': color_number += 1; break;
  747.     case 'g': color_number += 2; break;
  748.     case 'y': color_number += 3; break;
  749.     case 'm': color_number += 5; break;
  750.     case 'c': color_number += 6; break;
  751.     case 'w': color_number += 7; break;
  752.     case 'b': if (color_name_[letter+2] = 'u') color_number += 4; break;
  753.   }
  754.   return (color_number);
  755. }
  756.  
  757.  
  758.  
  759.  
  760. /********************************************************************/
  761. int Write_Obul_Prm ()
  762. {
  763.   short status;
  764.   short i;
  765.   int len;
  766.   char line[133];
  767.   FILE *_f;
  768.  
  769.   if ((_f = fopen( prm_file_, "wb" ) ) == 0)
  770.   {
  771.     return (1);
  772.   }
  773.   fwrite (&header, sizeof(header), 1, _f);
  774.   fwrite (bullet, header.number_of_bulletins*sizeof(struct obul_002_bullet), 1, _f);
  775.   fwrite( &n_help_text, sizeof(n_help_text), 1, _f);
  776.   for( i=0; i<n_help_text; i++ )
  777.     fwrite( &(help_text_[i][0]), 80, 1, _f );
  778.  
  779.   fclose (_f);
  780.   return (0);
  781. }
  782.  
  783.  
  784.  
  785.  
  786. /********************************************************************/
  787. int Read_Obul_Prm ()
  788. {
  789.   short status;
  790.   short i;
  791.   int len;
  792.   FILE *_f;
  793.  
  794.   if ((_f = fopen( prm_file_, "rb" ) ) == 0)
  795.   {
  796.     return( 1 );
  797.   }
  798.  
  799.   fread (&header, sizeof(header), 1, _f);
  800.   bullet = (struct obul_002_bullet *) calloc (1, header.number_of_bulletins*sizeof (struct obul_002_bullet));
  801.   fread (bullet, header.number_of_bulletins*sizeof(struct obul_002_bullet), 1, _f);
  802.   fread( &n_help_text, sizeof(n_help_text), 1, _f);
  803.   for( i=0; i<n_help_text; i++ )
  804.     fread( &(help_text_[i][0]), 80, 1, _f );
  805.   fclose (_f);
  806.   return (0);
  807. }
  808.  
  809.  
  810.  
  811.  
  812. /********************************************************************/
  813. int Write_Obul_Ctl ()
  814. {
  815.   short status;
  816.   short i;
  817.   int len;
  818.   FILE *_f;
  819.  
  820.   /*kef - output to console instead of directly into CTL file
  821.   if ((_f = fopen( ctl_file_, "w" ) ) == 0)
  822.   {
  823.     return (1);
  824.   }*/
  825.   _f = stdout;
  826.     
  827.   fprintf(_f,"# OBUL.CTL  Version %03d\n", VERSION );
  828.   fprintf(_f,"#\n");
  829.   fprintf(_f,"# Created with 'obul -d' on %s", ctime(&_now) );
  830.   fprintf(_f,"#\n");
  831.   fprintf(_f,"# Opus Bulletin Utilization Language\n");
  832.   fprintf(_f,"# Copyright 1991  Keith Ford - All Rights Reserved\n");
  833.   fprintf(_f,"# Micro Magic BBS, (205) 830-2362, 1:373/12, umagic.fidonet.org\n");
  834.   fprintf(_f,"# Supports IBM/Apple2, running 3/12/24-8N1\n");
  835.   fprintf(_f,"# SnailMail: 203 Creek Trail, Madison, AL, 35758, USA\n");
  836.   fprintf(_f,"#\n");
  837.   fprintf(_f,"# Data is case sensitive, keywords should be lower case.\n");
  838.   fprintf(_f,"# Lines that begin with the '#' character are ignored, except\n");
  839.   fprintf(_f,"# for HELP TEXT which is a key for file I/O.  Tabs and spaces\n");
  840.   fprintf(_f,"# are considered white space and will be used as delimiter\n");
  841.   fprintf(_f,"\n\n\n");
  842.  
  843.   fprintf(_f,"# OBUL.CTL VERSION NUMBER\n");
  844.   fprintf(_f,"version %03d\n\n",header.version);
  845.  
  846.   fprintf(_f,"# FULL PATH FOR LASTUS##.DAT FILE\n");
  847.   fprintf(_f,"lastpath\t\t%s\n\n",header.lastpath_);
  848.  
  849.   fprintf(_f,"# PATH FOR OUPUT OF THE BULLETIN MENU FILE (NO FILE SUFFIX)\n");
  850.   fprintf(_f,"path\t\t\t%s\n\n",header.path_);
  851.  
  852.   fprintf(_f,"# GENERATE .BBS OR .OEC FILES\n");
  853.   fprintf(_f,"bbs\t\t\t%s\n",(header.bbs?"YES":"NO"));
  854.   fprintf(_f,"oec\t\t\t%s\n\n",(header.oec?"YES":"NO"));
  855.  
  856.   fprintf(_f,"# NUMBER OF COLUMNS TO USE FOR BULLETIN MENU ENTRIES\n");
  857.   if (header.columns) fprintf(_f,"columns\t\t\t%d\n\n",header.columns);
  858.   else fprintf(_f,"columns\t\t\tautomatic\n\n");
  859.  
  860.   fprintf(_f,"# MAKE LEFT-TO-RIGHT (ACROSS) OR TOP-TO-BOTTOM (DOWN) FORMAT\n");
  861.   fprintf(_f,"order\t\t\t%s\n\n",(header.order?"across":"down"));
  862.  
  863.   fprintf(_f,"# TITLE SPECIFICATIONS\n");
  864.   fprintf(_f,"title_text\t\t%s\n",header.title_text_);
  865.   fprintf(_f,"title_color\t\t%s\n",header.title_color_);
  866.   fprintf(_f,"prompt_color\t\t%s\n\n",header.prompt_color_);
  867.  
  868.   fprintf(_f,"# GLOBAL BULLETIN SPECIFICATIONS\n" );
  869.   fprintf(_f,"display_privileged\t%s\n",(header.display_privileged?"yes":"no"));
  870.   fprintf(_f,"format\t\t\t%s\n",header.format_);
  871.   fprintf(_f,"lead_character\t\t%c\n",header.lead_character);
  872.   fprintf(_f,"lead_color\t\t%s\n",header.lead_color_);
  873.   fprintf(_f,"choice_color\t\t%s\n",header.choice_color_);
  874.   fprintf(_f,"tail_character\t\t%c\n",header.tail_character);
  875.   fprintf(_f,"tail_color\t\t%s\n",header.tail_color_);
  876.   fprintf(_f,"entry_color\t\t%s\n",header.entry_color_);
  877.   fprintf(_f,"highlight_character\t%c\n",header.highlight_character);
  878.   fprintf(_f,"highlight_color\t\t%s\n",header.highlight_color_);
  879.   fprintf(_f,"highlight_blink\t\t%s\n\n",(header.highlight_blink?"yes":"no"));
  880.  
  881.   /* get rid of Help & Credits */
  882.   header.number_of_bulletins -= 2;
  883.   for (i=0; i<header.number_of_bulletins; i++)
  884.   {
  885.     fprintf(_f,"# BULLETIN SPECIFICATION #%02d\n",i+1);
  886.     fprintf(_f,"choice_character\t%c\n", bullet[i].choice_character);
  887.     fprintf(_f,"entry_text\t\t%s\n", bullet[i].entry_text_);
  888.     fprintf(_f,"access\t\t\t%c\n", bullet[i].access);
  889.     fprintf(_f,"file\t\t\t%s\n", bullet[i].file_);
  890.     switch( bullet[i].highlight_mode )
  891.     {
  892.       case 0:
  893.         fprintf(_f,"highlight_mode\t\tnever\n\n" );
  894.         break;
  895.       case 1:
  896.         fprintf(_f,"highlight_mode\t\talways\n\n" );
  897.         break;
  898.       case 2:
  899.         fprintf(_f,"highlight_mode\t\tautomatic\n\n" );
  900.         break;
  901.     }
  902.   }
  903.  
  904.   fprintf(_f,"\n# HELP TEXT\n");
  905.   for (i=0; i<n_help_text; i++)
  906.     fprintf(_f,"%s",help_text_[i]);
  907.  
  908.   /*kef fclose (_f);*/
  909.   fflush(stdout);
  910.   return (0);
  911. }
  912.  
  913.  
  914.  
  915.  
  916. /********************************************************************/
  917. int Write_Obul_Menu ()
  918. {
  919.   short status;
  920.   short i,j,k,l,m,n,x;
  921.   short num_rows, extra_space;
  922.   short show_help, space_per_column;
  923.   int len;
  924.   FILE *_fbbs,*_foec;
  925.  
  926.   
  927.   if (header.oec)
  928.   {
  929.     j = header.columns;
  930.     extra_space = space_per_column = 0;
  931.     for (i=0; i<num_bulletins_available; i++)
  932.       space_per_column = MAX( strlen( bullet[ba[i]].entry_text_ ), space_per_column );
  933.     for( i=0; i<strlen(header.format_); i++ )
  934.       if( header.format_[i] != 'e' )  ++extra_space;
  935.     /* 3 for seraration */
  936.     space_per_column += (3 + extra_space);
  937.     header.columns = (num_columns-3) / space_per_column;
  938.     if(( j ) && ( header.columns > j ))  header.columns = j;
  939.     show_help = num_bulletins_available % header.columns;
  940.     num_rows = ((double)num_bulletins_available / header.columns) + 0.99;
  941.  
  942.     strcpy (string_, header.path_);
  943.     strcat (string_, ".oec");
  944.     if ((_fbbs = fopen (string_, "w")) != 0)
  945.     {
  946.       fprintf( _fbbs, "[/loop]\n[cls]\n" );
  947.       fprintf( _fbbs, "[%s]%s\n", header.title_color_, header.title_text_);
  948.       fprintf( _fbbs, "[blue]Prepared by OBUL %03d on [date]\n",VERSION);
  949.       fprintf( _fbbs, "[cyan]\n");
  950.  
  951.       for( k=0; k<num_rows; k++ )
  952.       {
  953.         i = k - num_rows;
  954.         for( j=0; j<header.columns; j++ )
  955.         {
  956.           if (header.order)  /*across*/
  957.           {
  958.             i = (k * header.columns) + j;
  959.           }
  960.           else
  961.           {
  962.             if (num_bulletins_available % header.columns)
  963.             {
  964.               if (j > (num_bulletins_available % header.columns))
  965.                 i+= (num_rows-1);
  966.               else if ((j >= (num_bulletins_available % header.columns)) &&
  967.                        (k==num_rows-1))
  968.                 i = num_bulletins_available;    /* make next IF fail */
  969.               else
  970.                 i+= num_rows;
  971.             }
  972.             else
  973.               i+= num_rows;
  974.           }
  975.           if (i<num_bulletins_available)
  976.           {
  977.             Format_Entry( ba[i], _fbbs, header.oec );
  978.             if (j != header.columns-1)
  979.               for (x=0; x<space_per_column-extra_space-strlen(bullet[ba[i]].entry_text_); x++)
  980.                 fprintf( _fbbs, " " );
  981.           }
  982.         }
  983.         fprintf( _fbbs, "\n" );
  984.       }
  985.       fprintf( _fbbs, "[cyan]\n" );
  986.  
  987.       if (lu.user.times)
  988.       {
  989.         if (any_new)
  990.         {
  991.           if (any_new==1)
  992.             fprintf( _fbbs,"[%s][fname], 1 updated bulletin, marked with ", header.title_color_ );
  993.           else
  994.             fprintf( _fbbs,"[%s][fname], %d updated bulletins, marked with ", header.title_color_, any_new );
  995.           fprintf( _fbbs, "[%s]", header.highlight_color_ );
  996.           if( header.highlight_blink ) fprintf( _fbbs, "[blink]" );
  997.           fprintf( _fbbs,"%c[%s]\n", header.highlight_character, header.title_color_ );
  998.         }
  999.       }
  1000.       else
  1001.       {
  1002.         fprintf( _fbbs,"[%s]This is your first visit [fname], please read [%s]all[%s] bulletins.\n",
  1003.           header.title_color_ ,header.highlight_color_, header.title_color_ );
  1004.       }
  1005.       fprintf( _fbbs, "[cyan]\n" );
  1006.       fprintf( _fbbs, "[%s]Enter Selection: [menu][[", header.prompt_color_);
  1007.       for (i=0; i<num_bulletins_available; i++)
  1008.       {
  1009.         fprintf( _fbbs, "%c", bullet[ba[i]].choice_character );
  1010.       }
  1011.       fprintf( _fbbs, "] \n" );
  1012.       for (i=0; i<num_bulletins_available; i++)
  1013.       {
  1014.         if (!bullet[ba[i]].access)
  1015.           fprintf( _fbbs, "[choice]%c[goto][privileged]\n", bullet[ba[i]].choice_character );
  1016.         else if( !strncmp( bullet[ba[i]].file_, "*quit", 5))
  1017.           fprintf( _fbbs, "[choice]%c[cls][quit]\n", bullet[ba[i]].choice_character );
  1018.         else if( !strncmp( bullet[ba[i]].file_, "*hangup", 7))
  1019.           fprintf( _fbbs, "[choice]%c[cls]Disconnecting...[hangup]\n", bullet[ba[i]].choice_character );
  1020.         else if( bullet[ba[i]].choice_character == '=' )
  1021.           fprintf( _fbbs, "[choice]%c[goto][credit]\n", bullet[ba[i]].choice_character );
  1022.         else if( bullet[ba[i]].choice_character == '?' )
  1023.           fprintf( _fbbs, "[choice]%c[goto][help]\n", bullet[ba[i]].choice_character );
  1024.         else
  1025.           fprintf( _fbbs, "[choice]%c[display]%s\n", bullet[ba[i]].choice_character, bullet[ba[i]].file_ );
  1026.       }
  1027.       fprintf( _fbbs, "[goto][loop]\n" );
  1028.       fprintf( _fbbs, "[/privileged]\n");
  1029.       fprintf( _fbbs, "[%s]", header.prompt_color_ );
  1030.       fprintf( _fbbs, "Your privilege level does not grant you access to this item.[bell]\n\n" );
  1031.       fprintf( _fbbs, "[enter]\n");
  1032.       fprintf( _fbbs, "[goto][loop]\n" );
  1033.       fprintf( _fbbs, "[/help]\n" );
  1034.       fprintf( _fbbs, "[cls][%s]\n", header.prompt_color_ );
  1035.       for( i=0; i<n_help_text; i++ )
  1036.         fprintf( _fbbs, "%s", help_text_[i] );
  1037.       fprintf( _fbbs, "[enter]\n");
  1038.       fprintf( _fbbs, "[goto][loop]\n" );
  1039.       fprintf( _fbbs, "[/credit]\n" );
  1040.       fprintf( _fbbs, "[cls][%s]\n", header.prompt_color_ );
  1041.       for( i=0; i<n_credit_text; i++ )
  1042.         fprintf( _fbbs, "%s\n", credit_text_[i] );
  1043.       fprintf( _fbbs, "[enter]\n");
  1044.       fprintf( _fbbs, "[goto][loop]\n" );
  1045.       fclose( _fbbs );
  1046.     }
  1047.     if (header.bbs)
  1048.     {
  1049.       sprintf( string2_, "obuloecc %s %s.bbs", string_, header.path_ );
  1050.       system( string2_ );
  1051.     }
  1052.   }
  1053.   return (0);
  1054. }
  1055.  
  1056.  
  1057.  
  1058.  
  1059. /********************************************************************/
  1060. int Format_Entry( i, _f, outflag )
  1061. short i;
  1062. FILE *_f;
  1063. char outflag;  /* 0=bbs, 1=oec */
  1064. {
  1065. #include <time.h>
  1066. #ifndef UNIX
  1067. # include <sys\types.h>
  1068. # include <sys\stat.h>
  1069. #else
  1070. # include <sys/types.h>
  1071. # include <sys/stat.h>
  1072. #endif
  1073.   FILE *fd;
  1074.   int j;
  1075.   char star_flag;
  1076.   long ftime;
  1077.   struct stat buffer;
  1078.  
  1079.   if( outflag == 1 )
  1080.   {
  1081.     for( j=0; j<strlen(header.format_); j++ )
  1082.     {
  1083.       switch( header.format_[j] )
  1084.       {
  1085.         case 'l':
  1086.           fprintf( _f, "[%s]%c", header.lead_color_, header.lead_character );
  1087.           break;
  1088.     
  1089.         case 'c':
  1090.           fprintf( _f, "[%s]%c", header.choice_color_, bullet[i].choice_character );
  1091.           break;
  1092.     
  1093.         case 't':
  1094.           fprintf( _f, "[%s]%c", header.tail_color_, header.tail_character );
  1095.           break;
  1096.     
  1097.         case 'h':
  1098.           star_flag = (bullet[i].file_[0] == '*');
  1099.           if (!star_flag)
  1100.           {
  1101.             stat( bullet[i].file_, &buffer );
  1102.             ftime = buffer.st_mtime;
  1103.             fprintf(log_file,"file: %s, %s",bullet[i].file_,ctime(&ftime));
  1104.           }
  1105.           else
  1106.           {
  1107.             if (bullet[i].highlight_mode == 2) bullet[i].highlight_mode = 0;
  1108.           }
  1109.           if ((bullet[i].highlight_mode == 0) ||
  1110.                ((bullet[i].highlight_mode == 2) && (ftime < lu.user.ludate)
  1111.                 && (lu.user.times)))
  1112.           {
  1113.             fprintf( _f, " " );
  1114.           }
  1115.           else
  1116.           {
  1117.             ++any_new;
  1118.             fprintf( _f, "[%s]", header.highlight_color_ );
  1119.             if( header.highlight_blink ) fprintf( _f, "[blink]" );
  1120.             fprintf( _f,"%c", header.highlight_character );
  1121.           }
  1122.           break;
  1123.  
  1124.         case 'e':
  1125.           fprintf( _f, "[%s]%s", header.entry_color_, bullet[i].entry_text_ );
  1126.           break;
  1127.  
  1128.         default:
  1129.           fprintf( _f, "%c", header.format_[j] );
  1130.           break;
  1131.       }
  1132.     }
  1133.   }
  1134. }
  1135.